/*
 * @Author: Snitro
 * @Date: 2021-05-13 19:55:23
 * @LastEditors: Snitro
 * @LastEditTime: 2021-05-23 13:01:03
 * @Description: file content
 */

#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))

#include "FORM_Painter.h"

int pos[10000][2], pos_size;

int x_line_pos = 0;
int y_line_pos = 0;

int left_pos = 0;
int bottom_pos = 0;

int fH = 0;

int min_x, min_y, max_x, max_y;

void clear_data() { pos_size = 0; }

void add_data(int x, int y) {
    int i;
    for (i = pos_size - 1; i >= 0; i--) {
        if (pos[i][0] > x) {
            pos[i + 1][0] = pos[i][0];
            pos[i + 1][1] = pos[i][1];
        } else
            break;
    }

    pos[i + 1][0] = x;
    pos[i + 1][1] = y;

    pos_size++;
}

void add_left_pos(int add) {
    left_pos += add;

    if (left_pos < 0) left_pos = 0;

    add_yline_pos(0);
}

void add_bottom_pos(int add) {
    bottom_pos += add;

    if (bottom_pos < 0) bottom_pos = 0;

    add_xline_pos(0);
}

void reset_pos() {
    left_pos = 0;
    x_line_pos = 0;
    y_line_pos = 0;

    int i;

    for (i = 0; i < pos_size; i++) {
        if (!i) {
            min_x = max_x = pos[i][0];
            min_y = max_y = pos[i][1];
        } else {
            min_x = min(min_x, pos[i][0]);
            min_y = min(min_y, pos[i][1]);

            max_x = max(max_x, pos[i][0]);
            max_y = max(max_y, pos[i][1]);
        }
    }

    bottom_pos = (min_y + max_y) / 2;
}

void add_xline_pos(int add) {
    x_line_pos += add;
    if (x_line_pos >= 128 - 15)
        x_line_pos = 0;
    else if (x_line_pos < 0)
        x_line_pos = 128 - 15 - 1;

    int x, i;

    for (i = 0; i < pos_size; i++) {
        x = (pos[i][0] - left_pos) / 2000;

        if (x == x_line_pos) {
            y_line_pos = (pos[i][1] - bottom_pos) / 100;
            break;
        }
    }

    refresh_page2();
}

void add_yline_pos(int add) {
    y_line_pos += add;
    if (y_line_pos >= 64 - 10)
        y_line_pos = 0;
    else if (y_line_pos < 0)
        y_line_pos = 64 - 10 - 1;

    int y, i;

    for (i = 0; i < pos_size; i++) {
        y = (pos[i][1] - bottom_pos) / 100;

        if (y == y_line_pos) {
            x_line_pos = (pos[i][0] - left_pos) / 2000;
            break;
        }
    }

    refresh_page2();
}

void setfH(int f) {
    fH = f;
    setDatafH(f);
}

void refresh_page1() {
    if (!pos_size) {
        oled_fill(0x00);
        oled_p8x16str(12, 3, (int8*)"Begin Testing");
        return;
    }

    static uint8 bmp[64][128];

    memset(bmp, 0, sizeof(bmp));

    int x, y, i, j, k;

    int last_x, last_y;

    if (fH && fH >= min_x && fH <= max_x) {
        x = (int)((fH - min_x + 0.0) / (max_x - min_x) * 127);
        for (y = 0; y < 64 - 10; y += 2) bmp[y][x] = 255;
    }

    for (i = 0; i < pos_size; i++) {
        x = (int)((pos[i][0] - min_x + 0.0) / (max_x - min_x) * 127);
        y = (int)((63 - 10) -
                  ((pos[i][1] - min_y + 0.0) / (max_y - min_y) * (63 - 10)));

        if (i) {
            int temp = last_y, calc;
            for (j = last_x; j <= x; j++) {
                calc = j == x ? y
                              : (int)((j + 0.0 - last_x) / (x - last_x) *
                                          (y - last_y) +
                                      last_y);
                for (k = min(temp, calc); k <= max(temp, calc); k++)
                    if (k >= 0 && k < 64) bmp[k][j] = 255;

                temp = calc;
            }
        }

        last_x = x;
        last_y = y;
    }

    oled_dis_bmp(64, 128, (uint8*)bmp, 100);

    if (fH && fH >= min_x && fH <= max_x) {
        x = (int)((fH - min_x + 0.0) / (max_x - min_x) * 127);

        char str[] = "000.000K";
        str[0] += (fH % 1000000) / 100000;
        str[1] += (fH % 100000) / 10000;
        str[2] += (fH % 10000) / 1000;
        str[4] += (fH % 1000) / 100;
        str[5] += (fH % 100) / 10;
        str[6] += (fH % 10);

        oled_p6x8str(x > 64 ? 64 : x, 7, (int8*)str);
    }
}

void refresh_page2() {
    if (!pos_size) {
        oled_fill(0x00);
        oled_p8x16str(12, 3, (int8*)"Begin Testing");
        return;
    }

    static uint8 bmp[64][128];

    memset(bmp, 0, sizeof(bmp));

    int x, y, i, j, k;

    for (x = 15; x < 128; x++) {
        for (y = 0; y < 64 - 10; y++) {
            if (x - 15 == x_line_pos)
                bmp[y][x] = 255;
            else if ((((x - 15) * 2000 + left_pos) / 100000 !=
                          ((x - 14) * 2000 + left_pos) / 100000 ||
                      ((x - 15) * 2000 + left_pos) == 0) &&
                     y % 3 == 0)
                bmp[y][x] = 255;

            if ((63 - 10 - y) == y_line_pos)
                bmp[y][x] = 255;
            else if ((((63 - 10 - y) * 100 + bottom_pos) / 2000 !=
                          ((64 - 10 - y) * 100 + bottom_pos) / 2000 ||
                      ((63 - 10 - y) * 100 + bottom_pos) == 0) &&
                     x % 3 == 0)
                bmp[y][x] = 255;
        }
    }

    int last_x = 0, last_y = 0;

    for (i = 0; i <= pos_size; i++) {
        if (i == pos_size) {
            x = (pos[i - 1][0] - left_pos + 2500000) / 2000 + 15;
            y = 53;
        } else {
            x = (pos[i][0] - left_pos) / 2000 + 15;
            y = 63 - 10 - (pos[i][1] - bottom_pos) / 100;
        }

        if (i) {
            int temp = last_y, calc;
            for (j = max(15, last_x); j <= min(x, 127); j++) {
                calc = (j == x ? y
                               : (int)((j + 0.0 - last_x) / (x - last_x) *
                                           (y - last_y) +
                                       last_y));

                if (j != max(15, last_x))
                    for (k = min(temp, calc); k <= max(temp, calc); k++)
                        if (k >= 0 && k < 64 - 10) bmp[k][j] = 255;

                temp = calc;
            }
        }

        last_x = x;
        last_y = y;
    }

    oled_dis_bmp(64, 128, (uint8*)bmp, 100);

    for (int x = 15; x < 128; x++)
        if (((x - 15) * 2000 + left_pos) / 100000 !=
                ((x - 14) * 2000 + left_pos) / 100000 ||
            ((x - 15) * 2000 + left_pos) == 0) {
            char str[] = "0.0M";
            int num = ((x - 15) * 2000 + left_pos + 50000) / 100000;
            str[0] += num / 10;
            str[2] += num % 10;
            oled_p6x8str(x > 104 ? 104 : x, 7, (int8*)str);
        }

    for (int y = 0; y < 64 - 10; y++)
        if ((((63 - 10 - y) * 100 + bottom_pos) / 2000 !=
                 ((64 - 10 - y) * 100 + bottom_pos) / 2000 ||
             ((63 - 10 - y) * 100 + bottom_pos) == 0)) {
            oled_int16(0, y / 8,
                       ((63 - 10 - y) * 100 + bottom_pos + 1000) / 2000 * 20);
        }
}